package com.qianheng.kit.base.dto;

import com.qianheng.kit.base.enums.ScenceEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.util.Optional;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Function;
import java.util.stream.Collectors;

@Accessors(chain = true)
public class BizContext {
    private static final int maxSize = 100;

    @Getter
    @Setter
    private LogDTO logInfo = new LogDTO();
    @Getter
    @Setter
    private LogDTO logWarn = new LogDTO();
    @Getter
    @Setter
    private LogDTO logError = new LogDTO();
    @Getter
    @Setter
    private boolean enableTrace = false;

    @Getter
    @Setter
    private String barcode;
    @Getter
    @Setter
    private Long foreignId;
    @Getter
    @Setter
    private String foreignTb;
    @Getter
    @Setter
    private ScenceEnum scence;

    @Getter
    private ConcurrentLinkedQueue<BizContext> subContexts = new ConcurrentLinkedQueue<>();

    public void addSubBizContext(BizContext subContext) {
        if (subContexts.size() >= maxSize) {
            return;
        }
        subContexts.add(subContext);
    }

    /**
     * 主线程日志
     */
    public String print() {
        StringBuilder sb = new StringBuilder();
        if (barcode != null) {
            sb.append("barcode=").append(barcode).append(" ");
        }
        if (logInfo.getLogsb() != null && logInfo.getLogsb().length() > 0) {
            sb.append("info=").append(logInfo.getLogsb()).append(" ");
        }
        if (logWarn.getLogsb() != null && logWarn.getLogsb().length() > 0) {
            sb.append("warn=").append(logWarn.getLogsb()).append(" ");
        }
        if (logError.getLogsb() != null && logError.getLogsb().length() > 0) {
            sb.append("error=").append(logError.getLogsb());
        }
        return sb.toString();
    }

    public String printInfo() {
        return Optional.ofNullable(logInfo).map(LogDTO::getLogsb).map(StringBuilder::toString).orElse("");
    }

    public String printWarn() {
        return Optional.ofNullable(logWarn).map(LogDTO::getLogsb).map(StringBuilder::toString).orElse("");
    }

    public String printError() {
        return Optional.ofNullable(logError).map(LogDTO::getLogsb).map(StringBuilder::toString).orElse("");
    }

    public String printRecursivelyAll() {
        return collectRecursively(BizContext::print);
    }

    public String printRecursivelyInfo() {
        return collectRecursively(BizContext::printInfo);
    }

    public String printRecursivelyWarn() {
        return collectRecursively(BizContext::printWarn);
    }

    public String printRecursivelyError() {
        return collectRecursively(BizContext::printError);
    }

    /**
     * 递归获取BizContext信息并拼接，最多递归5层
     *
     * @param converter 转换函数，用于将BizContext转换为字符串
     * @return 拼接后的字符串
     */
    private String collectRecursively(Function<BizContext, String> converter) {
        return collectRecursively(converter, 5); // 默认最多5层
    }

    /**
     * 递归获取BizContext信息并拼接
     *
     * @param converter 转换函数，用于将BizContext转换为字符串
     * @param maxDepth  最大递归深度
     * @return 拼接后的字符串
     */
    private String collectRecursively(Function<BizContext, String> converter, int maxDepth) {
        if (maxDepth <= 0) {
            return ""; // 达到最大深度限制
        }

        StringBuilder result = new StringBuilder().append(converter.apply(this));

        // 递归处理子上下文
        if (subContexts != null && !subContexts.isEmpty() && maxDepth > 1) {
            String subResults = subContexts.stream()
                .map(subContext -> subContext.collectRecursively(converter, maxDepth - 1))
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining("##"));
            if (StringUtils.isNotBlank(subResults)) {
                result.append("子线程").append(maxDepth).append(":").append(subResults);
            }
        }
        return result.toString();
    }

}
